home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / TTYLINK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-30  |  7.8 KB  |  357 lines

  1. /* Internet TTY "link" (keyboard chat) server
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include "global.h"
  5. #include "commands.h"
  6. #ifndef MSDOS
  7. #include <time.h>
  8. #endif
  9. #include "mbuf.h"
  10. #include "socket.h"
  11. #include "telnet.h"
  12. #include "mailbox.h"
  13. #include "x.h"
  14. #include "stats.h"
  15.  
  16. #if !defined(_lint)
  17. static char rcsid[] OPTIONAL = "$Id: ttylink.c,v 1.21 1997/07/31 00:44:20 root Exp root $";
  18. #endif
  19.  
  20. #ifdef ALLSERV
  21. static int Sttylink = -1;    /* Protoype socket for service */
  22. int Attended = TRUE;            /* default to attended mode */
  23. static int Screening;           /* default to non-screened mode */
  24.  
  25. static char Tnbanner[] = "Welcome to TTY-Link at %s - The system is %s.\n";
  26. static char defaultDeny[] = "Sorry, but the SYSOP is unable to join you at this time...";
  27. extern const char SysopBusy[];
  28. extern char *Motd;
  29.  
  30. int ScreenedCall;
  31. char *ScreenedCaller;
  32. static int SCREENretries = 60;
  33. #ifdef SOUNDS
  34. static char *SCREENsound;
  35. static char *CONNECTsound;
  36. #endif
  37. static char *DENYstr;
  38.  
  39. int CHAToneshotBypass = 0;
  40.  
  41.  
  42.  
  43. int
  44. ttylstart(argc,argv,p)
  45. int argc;
  46. char *argv[];
  47. void *p OPTIONAL;
  48. {
  49. struct sockaddr_in lsocket;
  50. int s, type, i;
  51. char addr[MAXSOCKSIZE];
  52. int len = MAXSOCKSIZE;
  53. time_t nowtime;
  54.  
  55.     if (Sttylink != -1)
  56.         return 0;
  57.  
  58.     ksignal (Curproc, 0);    /* Don't keep the parser waiting */
  59.     chname (Curproc, "TTYlink listener");
  60.     server_disconnect_io ();
  61.     
  62.     lsocket.sin_family = AF_INET;
  63.     lsocket.sin_addr.s_addr = INADDR_ANY;
  64.     if (argc < 2)
  65.         lsocket.sin_port = IPPORT_TTYLINK;
  66.     else
  67.         lsocket.sin_port = (int16) atoi (argv[1]);
  68.  
  69.     Sttylink = socket (AF_INET, SOCK_STREAM, 0);
  70.     (void) bind (Sttylink, (char *)&lsocket, sizeof (lsocket));
  71.     (void) listen (Sttylink, 1);
  72.     for ( ; ; )    {
  73.         if ((s = accept (Sttylink, NULLCHAR, (int *)NULL)) == -1)
  74.             break;    /* Service is shutting down */
  75.         
  76.         if (!Attended)    {
  77. busy:            usprintf (s, SysopBusy);
  78. close:            (void) shutdown (s, 1);
  79.             close_s (s);
  80.         } else {
  81.             if (Screening && !CHAToneshotBypass)    {
  82.                 while (ScreenedCall == -1)
  83.                     kpause (1000);
  84.                 usprintf (s, "Paging SYSOP, stand by....\n");
  85.                 usflush (s);
  86.                 ScreenedCall = -1;
  87. #ifdef SOUNDS
  88.                 if (SCREENsound)
  89.                     (void) playsound (SCREENsound);
  90.                 else
  91. #endif
  92.                     tcmdprintf ("\007");
  93.                 (void) time (&nowtime);        /* current time */
  94.                 if (getpeername (s, addr, &len) != -1)
  95.                     ScreenedCaller = strdup (psocket (addr));
  96.                 else
  97.                     ScreenedCaller = strdup ("unknown");
  98. #ifdef XSERVER
  99.                 xnotify (X_SCREEN);
  100. #endif
  101.                 tcmdprintf ("*** Incoming chat request from %s on %s\n",
  102.                     ScreenedCaller, ctime (&nowtime));
  103.                 for (i = 0; i < SCREENretries; i++)    {
  104.                     if (ScreenedCall != -1)
  105.                         break;
  106.                     kpause (1000);
  107.                 }
  108.                 free (ScreenedCaller);
  109.                 ScreenedCaller = NULLCHAR;
  110. #ifdef XSERVER
  111.                 xnotify (X_SCREEN);
  112. #endif
  113.                 switch (ScreenedCall)    {
  114.                     case 0:        /* denied */
  115.                         usprintf (s, "%s\n", (DENYstr && *DENYstr) ? DENYstr : defaultDeny);
  116.                         goto close;
  117.                     case -1:    /* unanswered */
  118.                         ScreenedCall = 0;
  119. #ifdef XSERVER
  120.                         xnotify (X_SCREEN);
  121. #endif
  122.                         goto busy;
  123.                     case 1:        /* accepted */
  124.                         usprintf (s, "Call accepted by SYSOP!\n");
  125.                         break;
  126.                     default:
  127.                         break;
  128.                 }
  129.             }
  130.             CHAToneshotBypass = 0;
  131.             type = TELNET;
  132.             if (newproc ("chat", 2048, ttylhandle, s, (void *)&type, NULL, 0) == NULLPROC)    {
  133.                 (void) shutdown (s, 1);
  134.                 close_s (s);
  135.             }
  136.         }
  137.     }
  138.     return 0;
  139. }
  140.  
  141.  
  142. /* This function handles all incoming "chat" sessions, be they TCP,
  143.  * NET/ROM or AX.25
  144.  */
  145. void
  146. ttylhandle (s, t, p)
  147. int s;
  148. void *t;
  149. void *p OPTIONAL;
  150. {
  151. int type, theindex;
  152. struct session *sp;
  153. char addr[MAXSOCKSIZE];
  154. int len = MAXSOCKSIZE;
  155. struct telnet tn;
  156. time_t nowtime;
  157. int validaddr;
  158.  
  159.     type = * (int *)t;
  160.     (void) sockmode (s, SOCK_ASCII);
  161.     (void) sockowner (s, Curproc);    /* We own it now */
  162.     log (s, "open %s", Sestypes[type]);
  163.  
  164.     /* Allocate a session descriptor */
  165.     if ((sp = newsession (NULLCHAR, type, 1)) == NULLSESSION)    {
  166.         tputs (TooManySessions);
  167.         close_s (s);
  168.         return;
  169.     }
  170. #ifdef STATS_USE
  171.     STATS_adduse (1);
  172.     MiscUsers++;
  173. #endif
  174.     theindex = sp - Sessions;
  175.  
  176.     /* Initialize a Telnet protocol descriptor */
  177.     memset ((char *)&tn, 0, sizeof (tn));
  178.     tn.session = sp;    /* Upward pointer */
  179.     sp->cb.telnet = &tn;    /* Downward pointer */
  180.     sp->s = s;
  181.     sp->proc = Curproc;
  182.  
  183.     (void) time (&nowtime);        /* current time */
  184.  
  185.     validaddr = getpeername (s, addr, &len);
  186. #ifdef SOUNDS
  187.     if (CONNECTsound)
  188.         (void) playsound (CONNECTsound);
  189.     else
  190. #endif
  191.         tputc ('\007');
  192.  
  193.     tprintf ("Incoming %s session %u from %s on %s",
  194.         Sestypes[type], theindex, (validaddr != -1) ? psocket(addr) : "unknown host", ctime (&nowtime));
  195.  
  196.     usprintf (s, Tnbanner, Hostname, Attended ? "attended" : "unattended");
  197.     if (Motd != NULLCHAR)
  198.         usprintf (s, "%s", Motd);
  199.  
  200.     tnrecv (&tn);
  201. #ifdef STATS_USE
  202.     MiscUsers--;
  203. #endif
  204. }
  205.  
  206.  
  207. /* Shut down Ttylink server */
  208. int
  209. ttyl0 (argc, argv, p)
  210. int argc OPTIONAL;
  211. char *argv[] OPTIONAL;
  212. void *p OPTIONAL;
  213. {
  214.     return (deleteserver (&Sttylink));
  215. }
  216.  
  217.  
  218. static int doretries (int argc,char *argv[],void *p);
  219. static int doattended (int argc,char *argv[],void *p);
  220. static int doscreening (int argc,char *argv[],void *p);
  221. static int doaccept (int argc,char *argv[],void *p);
  222. static int dodeny (int argc,char *argv[],void *p);
  223. static int dodenystr (int argc,char *argv[],void *p);
  224. #ifdef SOUNDS
  225. static int doscreensound (int argc,char *argv[],void *p);
  226. static int doconnectsound (int argc,char *argv[],void *p);
  227. #endif
  228.  
  229. /* chat subcommand table */
  230. static struct cmds CHATtab[] = {
  231.     { "accept",        doaccept,        0, 0, NULLCHAR },
  232.     { "attended",        doattended,        0, 0, NULLCHAR },
  233. #ifdef SOUNDS
  234.     { "connectsound",    doconnectsound,        0, 0, NULLCHAR },
  235. #endif
  236.     { "deny",        dodeny,            0, 0, NULLCHAR },
  237.     { "denystr",        dodenystr,        0, 0, NULLCHAR },
  238.     { "retries",        doretries,        0, 0, NULLCHAR },
  239.     { "screening",        doscreening,        0, 0, NULLCHAR },
  240. #ifdef SOUNDS
  241.     { "screensound",    doscreensound,        0, 0, NULLCHAR },
  242. #endif
  243. #if defined(MAILBOX) && defined(GATECMDS)
  244.     { "with",        dombchat,        0, 2, "chat with <bbsuser>" },
  245. #endif
  246.     { NULLCHAR,        NULL,            0, 0, NULLCHAR }
  247. };
  248.  
  249.  
  250. int
  251. chatcmd(argc,argv,p)
  252. int argc;
  253. char *argv[];
  254. void *p;
  255. {
  256.     return subcmd(CHATtab,argc,argv,p);
  257. }
  258.  
  259.  
  260. /* if unattended mode is set - restrict ax25, telnet and maybe other sessions */
  261. int
  262. doattended(argc,argv,p)
  263. int argc;
  264. char *argv[];
  265. void *p OPTIONAL;
  266. {
  267.     return setbool(&Attended,"Incoming Chat Attended",argc,argv);
  268. }
  269.  
  270.  
  271. /* if attended mode is set, do we screen the incoming calls? */
  272. int
  273. doscreening(argc,argv,p)
  274. int argc;
  275. char *argv[];
  276. void *p OPTIONAL;
  277. {
  278.     return setbool(&Screening,"Incoming Chat Screening",argc,argv);
  279. }
  280.  
  281.  
  282. /* if attended mode is set, do we screen the incoming calls? */
  283. int
  284. doretries(argc,argv,p)
  285. int argc;
  286. char *argv[];
  287. void *p OPTIONAL;
  288. {
  289.     return setint(&SCREENretries,"Time for Screened Callers to wait (in secs)",argc,argv);
  290. }
  291.  
  292.  
  293. /* to accept the waiting incoming call */
  294. int
  295. doaccept(argc,argv,p)
  296. int argc OPTIONAL;
  297. char *argv[] OPTIONAL;
  298. void *p OPTIONAL;
  299. {
  300.     ScreenedCall = 1;
  301.     return 0;
  302. }
  303.  
  304.  
  305. /* to deny the waiting incoming call */
  306. int
  307. dodeny(argc,argv,p)
  308. int argc OPTIONAL;
  309. char *argv[] OPTIONAL;
  310. void *p OPTIONAL;
  311. {
  312.     ScreenedCall = 0;
  313.     return 0;
  314. }
  315.  
  316.  
  317. int
  318. dodenystr(argc,argv,p)
  319. int argc;
  320. char *argv[];
  321. void *p OPTIONAL;
  322. {
  323.     if(argc < 2)    {
  324.         if (DENYstr)
  325.             tprintf ("%s\n", DENYstr);
  326.     } else {
  327.         if (DENYstr)
  328.             free (DENYstr);
  329.         DENYstr = strdup (argv[1]);
  330.     }
  331.     return 0;
  332. }
  333.  
  334.  
  335. #ifdef SOUNDS
  336. int
  337. doscreensound(argc,argv,p)
  338. int argc;
  339. char *argv[];
  340. void *p OPTIONAL;
  341. {
  342.     return (setsoundstr (argc, argv, &SCREENsound));
  343. }
  344.  
  345.  
  346. int
  347. doconnectsound(argc,argv,p)
  348. int argc;
  349. char *argv[];
  350. void *p OPTIONAL;
  351. {
  352.     return (setsoundstr (argc, argv, &CONNECTsound));
  353. }
  354. #endif /* SOUNDS */
  355.  
  356. #endif /*ALLSERV*/
  357.